home *** CD-ROM | disk | FTP | other *** search
- ;History:173,1
- page ,132
-
- .xlist
- include mintdefs.asm
- .list
-
- data segment byte public
- extrn formb: word
- extrn forme: word
- extrn fend: word
- extrn actptr: word
-
- comment /
- formhash is the hashing table for form names. It is a list of
- pointers to forms. Each form, in turn, has a pointer to the next form whose
- name hashes to the same entry in formhash. To add a new form, we must add the
- name to the proper place in the table. To delete a form, the form name must
- be removed from formhash. After the remaining forms have been moved up in
- memory, their links in formhash and each of the forms must be updated.
- We use -1 for NIL because is above any legal address that a form may
- take on. When we adjust the hash links, we won't adjust any NILs because they
- seem to be a form which is above the one being moved. /
-
- public syntax_table
- syntax_table dw NIL
- ;don't put anything here.
- formhashsize equ 256
- public formhash ;formhash is public for debugging purposes only.
- formhash dw formhashsize dup(NIL)
-
- hash_value dw ?
-
- data ends
-
- code segment byte public
-
- assume cs:code, ds: data, es: data
-
-
- ;define a form. Enter with:
- ; si => name
- ; cx = name length
- ; di => data
- ; dx = data length
- ; bx = form pointer.
-
- ;this is what is accomplished: (a=active string, n=new form, o=old forms)
- ; aaaa nnnnnnnn ooooooo oooooooo
- ; ^ ^ ^
- ;actptr formb forme
- ; ^<------>^
- ; di cx si
-
-
- public define_form
- define_form:
- push bx ;save the form pointer.
- call find_form ;see if it already exists.
- jnc define_form_1 ;it doesn't.
- ;check to see if the form is already big enough.
- cmp dx,[bx].data_length
- ja define_form_3 ;it isn't.
- pop [bx].form_pointer ;set the form pointer.
- mov si,di ;prepare to move the data.
- lea di,[bx].name_offset ;->name.
- add di,cx ;->data.
- mov [bx].data_length,dx ;set the data length.
- jmp short define_form_4
- define_form_3:
- push di
- push si
- push cx
- call delete_form
- pop cx
- pop si
- pop di
- define_form_1:
- pop bx ;restore form pointer.
- push di
- push si
- push cx
- add cx,(size form) ;compute amount of space needed.
- add cx,dx
- push cx ;push the size
- mov si,actptr
- mov di,si
- sub di,cx
- mov ax,di ;see if we have that much space.
- sub ax,free_space
- cmp ax,fend
- jb define_form_2 ;no, go show no mem
- mov cx,formb ;compute the number of bytes to move.
- sub cx,actptr
- mov actptr,di ;update actptr
- rep movsb
- ;di points to the free space. Leave it alone.
- mov formb,di
- pop [di].form_length ;get the total size. (pushed as cx)
- mov [di].form_pointer,bx
- pop cx ;we have to pop into cx, because we
- mov [di].name_length,cx ; need it later for the movsb.
- mov [di].data_length,dx
- pop si ;restore ->name
- call hash_func
- mov ax,[bx] ;get current formhash
- mov [bx],di ;make formhash point to us.
- mov [di].hash_link,ax ;make us point to current formhash.
- add di,name_offset ;lea di,[di].name_offset
- rep movsb
- pop si ;restore ->data
- define_form_4:
- ;here with dx=data size, si->data, di->data area in form.
- mov cx,dx
- rep movsb
- ret
- define_form_2:
- jmp nomem
-
-
- ;Find a form. Enter with:
- ; si => name
- ; cx = name length
- ;Preserve di
- ;Exit with:
- ; bx => form
- ; cy if form found,
- ; nc if form not found.
- public find_form
- find_form:
- push dx
- push di
- call hash_func
- mov hash_value,bx ;remember the formhash pointer.
- xor dx,dx
- mov bx,[bx] ;get ->first form that hashes here.
- find_form_1:
- cmp bx,NIL ;end of list?
- je find_form_2 ;yes, we didn't find it.
- cmp cx,[bx].name_length ;lengths equal?
- jne find_form_3 ;no, go to next.
- lea di,[bx].name_offset ;compare names.
- push si
- push cx
- rep cmpsb
- pop cx
- pop si
- jne find_form_3 ;names not equal.
- or dx,dx ;did we find it first?
- je find_form_4 ;yes - that's where we want it.
- mov di,hash_value ;get the head of the list.
- mov ax,[di]
- mov [di],bx ;make head -> found.
- xchg ax,[bx].hash_link ;make found -> old head.
- mov di,dx
- mov [di].hash_link,ax ;make pred(found) -> succ(found).
- find_form_4:
- stc ;found the form!
- pop di
- pop dx
- ret
- find_form_3:
- mov dx,bx
- mov bx,[bx].hash_link
- jmp find_form_1
- find_form_2:
- clc ;didn't find the form!
- pop di
- pop dx
- ret
-
-
- ;delete a form. Enter with:
- ; bx=>form
- ;this is what is accomplished: (a=active string, f=forms, d=deleted form)
- ; aaaa ffffffff ddddddddddd ffffffff
- ; ^ ^ ^ ^^^^^^^ ^
- ;actptr formb bx delete forme
- ; <-------------->^ ^
- ; cx si di
-
-
- public delete_form
- delete_form:
- ;delete the form from the hashing table.
- mov di,bx ;make a copy of the pointer to the form.
- mov cx,[bx].name_length
- lea si,[bx].name_offset
- call hash_func
- sub bx,hash_link ;pretend that formhash is a form itself.
- delete_form_1:
- cmp [bx].hash_link,di ;does this form point to us?
- je delete_form_2 ;yes.
- mov bx,[bx].hash_link ;no - go to the next form.
- jmp delete_form_1
- delete_form_2:
- mov ax,[di].hash_link ;unlink us from the list.
- mov [bx].hash_link,ax
- ;check for deletion of the syntax table.
- cmp di,syntax_table
- jne delete_form_7
- mov syntax_table,NIL ;if we're deleting it, put NIL in.
- delete_form_7:
- ;now adjust the hash links in formhash.
- mov ax,[di].form_length
- mov bx,offset syntax_table
- mov cx,formhashsize+1 ;add one for the syntax table.
- delete_form_3:
- cmp [bx],di ;do we need to adjust this one?
- jae delete_form_4 ;no.
- add [bx],ax ;yes - do it.
- delete_form_4:
- add bx,2
- loop delete_form_3
- ;now adjust all the hash links in the forms. Notice that we are adjusting
- ; the hash link in the form we are about to delete, but it doesn't hurt.
- ; We can also presume the existence of at least one form at this point.
- mov bx,formb
- delete_form_5:
- cmp [bx].hash_link,di ;do we need to adjust this one?
- jae delete_form_6 ;no.
- add [bx].hash_link,ax ;yes - do it.
- delete_form_6:
- add bx,[bx].form_length ;compute the form after this one.
- cmp bx,forme ;no forms after this one.
- jb delete_form_5
- add formb,ax
- mov si,di ;now move everything up.
- add di,ax
- mov cx,si
- sub cx,actptr
- dec si
- dec di
- std ;reverse move
- rep movsb
- cld
- inc di ;update actptr
- mov actptr,di
- ret
-
-
- ;find the form whose name is given in arg1. Return the form pointer in
- ;si, and the number of bytes remaining in the form in cx.
- public find_arg1
- find_arg1:
- mov cx,1
- ;fall through to find_arg
-
- ;find the form whose name is given in the argument specified in cx. Return
- ; the form pointer in si, and the number of bytes remaining in the form in cx,
- ; and the pointer to the form in bx.
- public find_arg
- find_arg:
- call getarg
- call find_form
- jnc find_arg1_1 ;if form doesn't exist, exit.
- mov si,bx ;make si => form.data
- add si,name_offset
- add si,[bx].name_length
- add si,[bx].form_pointer
- mov cx,[bx].data_length ;make cx = number of bytes left.
- sub cx,[bx].form_pointer
- stc ;remember that form was found.
- find_arg1_1:
- ret
-
-
- ;rehash is used when the hash structure is garbage, i.e., when a file has
- ; been bulk-loaded.
-
- public rehash
- rehash:
- mov di,offset formhash ;kill all of the current pointers.
- mov cx,formhashsize
- mov ax,NIL
- rep stosw
- mov di,formb
- rehash_1:
- lea si,[di].name_offset ;->name.
- mov cx,[di].name_length
- call hash_func
- mov ax,[bx] ;get current formhash
- mov [bx],di ;make formhash point to us.
- mov [di].hash_link,ax ;make us point to current formhash.
- add di,[di].form_length
- cmp di,forme
- jb rehash_1
- ret
-
-
- hash_func:
- ;enter with si,cx ->name to be hashed.
- ;the particular function we will use is:
- ; value=(((char*2+char)*2+char)*2+char)*2+char ...
- ;of course, most of the chars will be in the range [A-Za-z], so this
- ; may not be the best hashing function. Time will tell.
- ;exit with entry into hash table in bx.
- ;preserve dl.
- push si
- push cx
- xor bl,bl ;start with zero.
- jcxz hash_func_1
- hash_func_2:
- add bl,bl ;*2
- adc bl,0
- lodsb
- sub al,'a' ;subtract off the most probable char.
- add bl,al ;+char
- adc bl,0
- loop hash_func_2
- hash_func_1:
- mov bh,0
- add bx,bx
- lea bx,formhash[bx] ;don't add bx,offset formhash!
- pop cx
- pop si
- ret
-
-
- ;Adjust the form pointer after building a value which affects the
- ; form pointer. The new form pointer is derived from the count
- ; of characters left in cx. The form is pointed to by bx.
- public set_form_pointer
- set_form_pointer:
- mov ax,[bx].data_length
- sub ax,cx
- mov [bx].form_pointer,ax
- ret
-
- public return_form
- return_form:
- call set_form_pointer
- jmp return_tos
-
-
- extrn return_tos: near
- extrn getarg: near
- extrn nomem: near
- code ends
-
- end
-
-